package cn.xmoit.poi;

import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * @author fangyy
 */
public class WordUtil {

	static List<List<String>> data() {
		List<List<String>> list = new ArrayList<>();
		List<String> title = new ArrayList<>();
		title.add("姓名");
		title.add("班级");
		title.add("年龄");
		list.add(title);
		List<String> data1 = new ArrayList<>();
		data1.add("张三");
		data1.add("一班");
		data1.add("10");
		list.add(data1);
		List<String> data2 = new ArrayList<>();
		data2.add("李四");
		data2.add("二班");
		data2.add("10");
		list.add(data2);
		return list;
	}

	public static void main1(String[] args) {

		try {
			String inPath = "/Users/tonny/Downloads/1.doc";
			String outPath = "/Users/tonny/Downloads/2.doc";
			FileInputStream in = new FileInputStream(inPath);
			FileOutputStream out = new FileOutputStream(outPath);
			HWPFDocument doc = new HWPFDocument(in);

			Range range = doc.getRange();
			range.insertAfter("789");
			doc.write(out);
			out.close();

			// FileInputStream fis = new FileInputStream(new
			// File("/Users/tonny/Downloads/1.doc"));
			// FileOutputStream fos = new FileOutputStream(new
			// File("/Users/tonny/Downloads/2.docx"));
			//
			// // 将doc文件的内容读取到XWPFDocument对象中
			// HWPFDocument doc = new HWPFDocument(fis);
			// WordExtractor wordExtractor = new WordExtractor(doc);
			// String text = wordExtractor.getText();
			// XWPFDocument document2 = new XWPFDocument();
			// XWPFParagraph paragraph = document2.createParagraph();
			// XWPFRun run = paragraph.createRun();
			// run.setText(text);
			//
			// // 保存XWPFDocument对象到docx文件中
			// document2.write(fos);
			// fis.close();
			// fos.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * docx 与 doc 互转
	 * @param fileType 文档类型
	 */
	public static void convert(String fileType) {
		File inputWord = new File("/Users/tonny/Downloads/1.doc");
		File outputFile = new File("/Users/tonny/Downloads/zzz.docx");
		try (InputStream docxInputStream = Files.newInputStream(inputWord.toPath());
				OutputStream outputStream = Files.newOutputStream(outputFile.toPath())) {
			IConverter converter = LocalConverter.builder().build();
			boolean flag = false;
			// docx转doc
			if ("docx".equals(fileType)) {
				flag = converter.convert(docxInputStream)
					.as(DocumentType.DOCX)
					.to(outputStream)
					.as(DocumentType.DOC)
					.execute();
			}
			else if ("doc".equals(fileType)) {
				flag = converter.convert(docxInputStream)
					.as(DocumentType.DOC)
					.to(outputStream)
					.as(DocumentType.DOCX)
					.execute();
			}
			if (flag) {
				converter.shutDown();
			}
			System.out.println("转换成功");
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 利用 LibreOffice 将 Office 文档转换成 DOCX，该转换是异步的，返回时，转换可能还在进行中，转换是否有异常也未可知 libreoffice
	 * libreoffice --headless --invisible --convert-to docx /root/1.doc --outdir
	 * /root/test/
	 * @param source 目标文件
	 * @param target 输出文件夹
	 * @return 子线程执行完毕的返回值
	 */
	public static int convertToDocx(String source, String target) throws Exception {
		String command = String.format("libreoffice --headless --invisible --convert-to docx %s --outdir %s", source,
				target);
		System.out.println(command);
		return executeOSCommand(command);
	}

	/**
	 * 调用操作系统的控制台，执行 command 指令 执行该方法时，并没有等到指令执行完毕才返回，而是执行之后立即返回，返回结果为
	 * 0，只能说明正确的调用了操作系统的控制台指令。
	 */
	private static int executeOSCommand(String command) throws Exception {
		Process process;
		process = Runtime.getRuntime().exec(command);
		int exitStatus = process.waitFor();
		if (exitStatus == 0) {
			exitStatus = process.exitValue();
		}
		// 销毁子进程
		process.destroy();
		return exitStatus;
	}

	public static void main(String[] args) throws Exception {
		// addTable("D:\\1.doc", "D:\\2.docx", data(), "测试数据");
		convertToDocx("D:\\1.doc", "D:\\");
	}

	/**
	 * 添加表格
	 * @param source 来源
	 * @param target 目标
	 * @param list 数据
	 * @param title 标题
	 */
	public static void addTable(String source, String target, List<List<String>> list, String title) {
		if (CollectionUtils.isEmpty(list)) {
			// TODO 异常提醒
			return;
		}
		int rows = list.size();
		int columns = list.get(0).size();
		try (InputStream fis = new BufferedInputStream(Files.newInputStream(Paths.get(source)));
				OutputStream fos = new BufferedOutputStream(Files.newOutputStream(Paths.get(target)));
				XWPFDocument xwpfDocument = new XWPFDocument(fis)) {
			if (StringUtils.isNotBlank(title)) {
				// 创建一个段落
				XWPFParagraph p1 = xwpfDocument.createParagraph();
				XWPFRun r1 = p1.createRun();
				// 是否加粗
				r1.setBold(true);
				// 字体大小
				r1.setFontSize(12);
				// 添加内容
				r1.setText(title);
				// 换行
				r1.addCarriageReturn();
			}
			// 创建表格
			XWPFTable table = xwpfDocument.createTable(rows, columns);
			// 设置表格宽度
			CTTblPr tblPr = table.getCTTbl().getTblPr();
			tblPr.getTblW().setType(STTblWidth.DXA);
			tblPr.getTblW().setW(new BigInteger("9000"));
			// 表格数据填充
			for (int i = 0; i < list.size(); i++) {
				List<String> data = list.get(i);
				for (int j = 0; j < data.size(); j++) {
					table.getRow(i).getCell(j).setText(data.get(j));
				}
			}
			// 写数据
			xwpfDocument.write(fos);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

}
